import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) => MaterialApp(
        title: '第08课 - 列表与滚动',
        theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.indigo),
        home: const InfiniteListPage(),
      );
}

class InfiniteListPage extends StatefulWidget {
  const InfiniteListPage({super.key});
  @override
  State<InfiniteListPage> createState() => _InfiniteListPageState();
}

class _InfiniteListPageState extends State<InfiniteListPage> {
  final _controller = ScrollController();
  final List<String> _items = [];
  bool _isLoading = false;
  bool _hasMore = true;
  final int _limit = 10;

  @override
  void initState() {
    super.initState();
    _controller.addListener(_onScroll);
    _refresh();
  }

  void _onScroll() {
    if (_controller.position.pixels >=
            _controller.position.maxScrollExtent - 100 &&
        !_isLoading &&
        _hasMore) {
      _loadMore();
    }
  }

  Future<void> _refresh() async {
    setState(() {
      _items.clear();
      _hasMore = true;
    });
    await _loadMore();
  }

  Future<void> _loadMore() async {
    setState(() => _isLoading = true);
    try {
      final start = _items.length;
      final uri = Uri.parse(
          'https://jsonplaceholder.typicode.com/posts?_start=$start&_limit=$_limit');
      final resp = await http.get(uri);
      if (resp.statusCode == 200) {
        final List data = jsonDecode(resp.body) as List;
        if (data.isEmpty) {
          setState(() => _hasMore = false);
        } else {
          final titles = data
              .map((e) => (e['title'] as String?) ?? 'Untitled')
              .toList(growable: false);
          setState(() => _items.addAll(titles));
        }
      } else {
        if (!mounted) return;
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('加载失败: HTTP ${resp.statusCode}')),
        );
      }
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context)
          .showSnackBar(SnackBar(content: Text('加载异常: $e')));
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('无限加载列表'),
        actions: [
          IconButton(onPressed: _refresh, icon: const Icon(Icons.refresh)),
        ],
      ),
      body: RefreshIndicator(
        onRefresh: _refresh,
        child: ListView.separated(
          physics: const AlwaysScrollableScrollPhysics(),
          controller: _controller,
          itemCount: _items.length + 1,
          separatorBuilder: (_, __) => const Divider(height: 1),
          itemBuilder: (context, i) {
            if (i == _items.length) {
              return Padding(
                padding: const EdgeInsets.all(16),
                child: Center(
                  child: _isLoading
                      ? const CircularProgressIndicator()
                      : Text(_hasMore ? '到底了，继续滚动加载更多...' : '没有更多了'),
                ),
              );
            }
            return ListTile(title: Text(_items[i]));
          },
        ),
      ),
    );
  }
}